#include <io/Event_ROOT.h>
#include <io/SEvent_ROOT.h>
#include <io/StreamerSwitch.h>

#include <evt/Header.h>
#include <evt/Event.h>

#include <iostream>
#include <string>

#include <TFile.h>
#include <TSystem.h>
#include <TTree.h>
#include <TBranch.h>

#include "iOfflineFile.h"

using namespace std;
using namespace iOF;

iOfflineFile::iOfflineFile() :
    fNoEvents(0),
    fCurEventNo(-1),
    inputFile(0),
    fTree(0),
    fBranch(0),
    fConfigBranch(0),
    fCurEvent(0),
    fConfig(0)
{
  gSystem->Load("libAugerEventIO.so");
}

iOfflineFile::iOfflineFile(std::string filename) :
    fNoEvents(0),
    fCurEventNo(-1),
    inputFile(0),
    fTree(0),
    fBranch(0),
    fConfigBranch(0),
    fCurEvent(0),
    fConfig(0)
{
  gSystem->Load("libAugerEventIO.so");
  cout << "\nDentro del constructor de ioOfflineFile\n";
  if(Open(filename)==0) throw "ioError";
}

iOfflineFile::~iOfflineFile()
{
  if(inputFile){
    if(inputFile->IsOpen()) inputFile->Close();
    delete inputFile;
  }
}

bool iOfflineFile::Open(std::string filename) // return 0 if there is an error
{
  if(inputFile){
    if(inputFile->IsOpen()){
      inputFile->Close();
    }
  }
  inputFile =new TFile(filename.c_str());
  
  if(inputFile->IsZombie()){
    cout<< "\n\x1b[35mError en el archivo: "<<filename.c_str()<<"\n No se puede abrir\x1b[0m\n\n";
    return 0;
  }
  cout << "\nDespues de crear TFile.Open\n";
  
  fTree = dynamic_cast<TTree*>(inputFile->Get("AugerOffline"));
  if(!fTree){
    cout<< "\n\x1b[35mEl archivo: "<<filename.c_str()<<" no es un archivo Offline\x1b[0m\n\n";
    return 0;
  }
  cout << "\nDespues de TFile.Get\n";
  fBranch = fTree->GetBranch("Event");
  if(fCurEvent) delete fCurEvent;
  fCurEvent=new io::Event_ROOT();
  fBranch->SetAddress(&fCurEvent);
  fNoEvents=fTree->GetEntries();
  cout << "\n\x1b[33mHay "<<fNoEvents<<" eventos en el archivo\x1b[0m\n\n";
  fCurEventNo = -1;
  return 1;
}

bool iOfflineFile::Close()
{
  if(inputFile){
    if(inputFile->IsOpen()) inputFile->Close();
  }
  if(fCurEvent){
    delete fCurEvent;
    fCurEvent=0x0;
  }
  return 1;
}


bool iOfflineFile::ReadEvent(evt::Event& event)
{
  if(fCurEventNo == -1){
    cout << "\nNumero de evento no elegido\n";
    return 0;
  }
  fBranch->GetEntry(fCurEventNo);
  fCurEvent->Fill(&event);
  return 1;
}

bool iOfflineFile::ReadOnlySHeaderAndSTrigger(evt::Event& event)
{
  //---------------
  //Por ahora hace lo mismo que Read. Lo dejo por compatibilidad con la version anterior
  //y por si despues se me ocurre como hacer esto sin tener que leer el evento completo.
  //---------------
  if(fCurEventNo == -1){
    cout << "\nNumero de evento no elegido\n";
    return 0;
  }
  fBranch->GetEntry(fCurEventNo);
  fCurEvent->Fill(&event);
  return 1;
}

int iOfflineFile::GetNEvents()
{
  return fNoEvents;
}

std::string iOfflineFile::GetConfig()
{
  string str;
  return str;
}

bool iOfflineFile::SetCurEventNo(int curEventNo)
{
  if(curEventNo<0 || curEventNo >= fNoEvents){
    cout << "\nNumero de evento invalido\n";
    return 0;
  }
  fCurEventNo=curEventNo;
  return 1;
}

